import yfinance as yf¶
import pandas as pd
data = yf.download('RELIANCE.NS', start='2023-01-01', end='2024-01-01')
print(data)
In [3]:
data.describe()
Out[3]:
| Price | Close | High | Low | Open | Volume | SMA50 | SMA200 | Signal |
|---|---|---|---|---|---|---|---|---|
| Ticker | RELIANCE.NS | RELIANCE.NS | RELIANCE.NS | RELIANCE.NS | RELIANCE.NS | |||
| count | 245.000000 | 245.000000 | 245.000000 | 245.000000 | 2.450000e+02 | 196.000000 | 46.000000 | 245.000000 |
| mean | 1158.515832 | 1167.544031 | 1150.101075 | 1159.618830 | 1.342906e+07 | 1155.458936 | 1154.968559 | 0.187755 |
| std | 68.996361 | 69.028158 | 68.241882 | 67.986717 | 6.566007e+06 | 58.423981 | 6.880815 | 0.391316 |
| min | 1008.876465 | 1017.469976 | 999.137156 | 1015.178381 | 3.854810e+06 | 1067.407145 | 1148.026281 | 0.000000 |
| 25% | 1113.739990 | 1121.027318 | 1105.627760 | 1115.504712 | 9.209636e+06 | 1093.980308 | 1148.742854 | 0.000000 |
| 50% | 1155.154419 | 1163.078321 | 1151.940330 | 1157.188818 | 1.203256e+07 | 1168.875358 | 1152.738733 | 0.000000 |
| 75% | 1209.391479 | 1217.368326 | 1203.415681 | 1211.886930 | 1.578266e+07 | 1203.694152 | 1159.946151 | 0.000000 |
| max | 1302.476196 | 1308.961472 | 1289.050059 | 1301.133996 | 5.708188e+07 | 1243.968442 | 1170.063072 | 1.000000 |
In [5]:
import yfinance as yf
import matplotlib.pyplot as plt
# Download historical data for Reliance Industries Limited
ticker = "RELIANCE.NS"
data = yf.download(ticker, start="2023-01-01", end="2024-01-01")
# Plot closing prices
plt.figure(figsize=(12, 6))
plt.plot(data.index, data['Close'], label='Close Price', color='blue',marker='o')
plt.title(f'{ticker} Trade Chart (2024)')
plt.xlabel('Date')
plt.ylabel('Price (INR)')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
[*********************100%***********************] 1 of 1 completed
In [7]:
data.info()
<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 245 entries, 2023-01-02 to 2023-12-29 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 (Close, RELIANCE.NS) 245 non-null float64 1 (High, RELIANCE.NS) 245 non-null float64 2 (Low, RELIANCE.NS) 245 non-null float64 3 (Open, RELIANCE.NS) 245 non-null float64 4 (Volume, RELIANCE.NS) 245 non-null int64 dtypes: float64(4), int64(1) memory usage: 11.5 KB
In [19]:
import yfinance as yf
import pandas as pd
data = yf.download('RELIANCE.NS', start='2023-01-01', end='2024-01-01')
# Preview the data
print(data)
[*********************100%***********************] 1 of 1 completed
Price Close High Low Open Volume Ticker RELIANCE.NS RELIANCE.NS RELIANCE.NS RELIANCE.NS RELIANCE.NS Date 2023-01-02 1180.586060 1182.006865 1167.890577 1168.715541 5316175 2023-01-03 1171.946655 1179.256896 1167.707271 1175.613232 7658932 2023-01-04 1154.301392 1173.780010 1152.216007 1171.923749 9264891 2023-01-05 1152.239014 1162.482516 1147.632911 1156.570169 13637099 2023-01-06 1162.711548 1167.776018 1154.186834 1158.013796 6349597 ... ... ... ... ... ... 2023-12-22 1278.186890 1286.085010 1269.516244 1275.471131 16541784 2023-12-26 1284.664917 1291.591360 1277.015829 1279.656890 7465664 2023-12-27 1289.050049 1295.552881 1282.198303 1286.633203 9204156 2023-12-28 1298.368408 1301.582475 1289.050059 1290.520045 12302636 2023-12-29 1288.103149 1302.579043 1285.287754 1301.133996 10864584 [245 rows x 5 columns]
In [1]:
import yfinance as yf
import plotly.graph_objects as go
def plot_candlestick_range(ticker, start_date, end_date):
try:
data = yf.download(ticker, start=start_date, end=end_date)
fig = go.Figure(data=[go.Candlestick(x=data.index,
open=data['Open'],
high=data['High'],
low=data['Low'],
close=data['Close'])])
fig.update_layout(
title=f'{ticker} Candlestick Chart ({start_date} to {end_date})',
xaxis_title='Date',
yaxis_title='Price (INR)',
xaxis_rangeslider_visible=False
)
fig.show()
except Exception as e:
print(f"An error occurred: {e}")
print(f"Could not retrieve data for {ticker} between {start_date} and {end_date}. Please check the ticker symbol or date range.")
if __name__ == "__main__":
stock_ticker = "RELIANCE.NS"
start_date = "2023-01-01"
end_date = "2024-01-01"
plot_candlestick_range(stock_ticker, start_date, end_date)
YF.download() has changed argument auto_adjust default to True
[*********************100%***********************] 1 of 1 completed
1 Failed download:
['RELIANCE.NS']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
In [17]:
import yfinance as yf
import pandas as pd
# Download historical data
data = yf.download('INFOSYS.NS', start='2023-01-01', end='2024-01-01')
# Calculate moving averages
data['SMA50'] = data['Close'].rolling(window=50).mean()
data['SMA200'] = data['Close'].rolling(window=200).mean()
# Generate trading signals
data['Signal'] = 0
data.loc[data['SMA50'] > data['SMA200'], 'Signal'] = 1
data.loc[data['SMA50'] < data['SMA200'], 'Signal'] = -1
print(data[['Close', 'SMA50', 'SMA200', 'Signal']].tail(10))
[*********************100%***********************] 1 of 1 completed
Price Close SMA50 SMA200 Signal Ticker RELIANCE.NS Date 2023-12-15 1243.579346 1173.710940 1161.310849 1 2023-12-18 1256.236328 1175.772444 1162.140546 1 2023-12-19 1274.723633 1178.204189 1163.088803 1 2023-12-20 1259.300903 1180.288613 1163.922823 1 2023-12-21 1276.941162 1182.922676 1164.881366 1 2023-12-22 1278.186890 1185.480496 1165.949947 1 2023-12-26 1284.664917 1187.802615 1167.001992 1 2023-12-27 1289.050049 1190.169084 1168.116869 1 2023-12-28 1298.368408 1192.722917 1169.142331 1 2023-12-29 1288.103149 1195.123767 1170.063072 1
In [23]:
import yfinance as yf
import pandas as pd
import numpy as np
#ZSCORE
def calculate_z_score(series, window):
rolling_mean = series.rolling(window=window).mean()
rolling_std = series.rolling(window=window).std()
return (series - rolling_mean) / rolling_std
def pairs_trading_strategy(ticker1, ticker2, lookback_window, entry_threshold, exit_threshold):
data = yf.download([f"{ticker1}.NS", f"{ticker2}.NS"], period="1y")['Close']
data = data.dropna()
spread = data[f"{ticker1}.NS"] - data[f"{ticker2}.NS"]
z_score = calculate_z_score(spread, window=lookback_window)
signals = pd.DataFrame(index=z_score.index)
signals['position'] = 0
signals.loc[z_score < -entry_threshold, 'position'] = 1
signals.loc[z_score > entry_threshold, 'position'] = -1
signals.loc[(signals['position'].shift(1) == 1) & (z_score > -exit_threshold), 'position'] = 0
signals.loc[(signals['position'].shift(1) == -1) & (z_score < exit_threshold), 'position'] = 0
return signals, z_score
ticker1 = "RELIANCE"
ticker2 = "TCS"
lookback = 20
entry = 2
exit = 0
signals, z_scores = pairs_trading_strategy(ticker1, ticker2, lookback, entry, exit)
print(signals)
print(z_scores)
[*********************100%***********************] 2 of 2 completed
position
Date
2024-04-25 0
2024-04-26 0
2024-04-29 0
2024-04-30 0
2024-05-02 0
... ...
2025-04-21 0
2025-04-22 0
2025-04-23 0
2025-04-24 0
2025-04-25 0
[248 rows x 1 columns]
Date
2024-04-25 NaN
2024-04-26 NaN
2024-04-29 NaN
2024-04-30 NaN
2024-05-02 NaN
...
2025-04-21 1.192566
2025-04-22 1.098692
2025-04-23 0.413799
2025-04-24 0.442566
2025-04-25 0.036431
Length: 248, dtype: float64
In [25]:
def bollinger_bands_strategy(ticker, period=20, std_dev=2, lookback="30d"):
df = yf.download(f"{ticker}.NS", period=lookback)
if df.empty:
print(f"Could not retrieve data for {ticker} for the period: {lookback}.")
return pd.DataFrame()
close_prices = df['Close'].dropna()
print("\nShape of 'close_prices' (pandas Series):", close_prices.shape)
print("First few rows of 'close_prices':\n", close_prices.head())
indicator = ta.volatility.BollingerBands(close=close_prices, window=period, window_dev=std_dev)
bb_mid = indicator.bollinger_mavg()
bb_upper = indicator.bollinger_hband()
bb_lower = indicator.bollinger_lband()
results_df = pd.DataFrame({'Close': close_prices, 'bb_mid': bb_mid, 'bb_upper': bb_upper, 'bb_lower': bb_lower})
import yfinance as yf
import pandas as pd
import ta
import numpy as np
def bollinger_bands_strategy(ticker, period=20, std_dev=2, lookback="30d"):
df = yf.download(f"{ticker}.NS", period=lookback)
if df.empty:
print(f"Could not retrieve data for {ticker} for the period: {lookback}.")
return pd.DataFrame()
close_prices = df['Close'].dropna()
print("\nShape of 'close_prices' (pandas Series):", close_prices.shape)
print("First few rows of 'close_prices':\n", close_prices.head())
indicator = ta.volatility.BollingerBands(close=close_prices, window=period, window_dev=std_dev)
bb_mid = indicator.bollinger_mavg()
bb_upper = indicator.bollinger_hband()
bb_lower = indicator.bollinger_lband()
results_df = pd.DataFrame({'Close': close_prices, 'bb_mid': bb_mid, 'bb_upper': bb_upper, 'bb_lower': bb_lower})
results_df['squeeze_on'] = (results_df['bb_upper'] - results_df['bb_lower']) <= (results_df['bb_mid'].rolling(period).std() * 2)
results_df['squeeze_breakout_long'] = (results_df['Close'] > results_df['bb_upper']) & (results_df['squeeze_on'].shift(1) == True)
results_df['squeeze_breakout_short'] = (results_df['Close'] < results_df['bb_lower']) & (results_df['squeeze_on'].shift(1) == True)
return results_df[['Close', 'bb_lower', 'bb_mid', 'bb_upper', 'squeeze_on', 'squeeze_breakout_long', 'squeeze_breakout_short']]
if __name__ == "__main__":
ticker = "RELIANCE"
results_df = bollinger_bands_strategy(ticker, lookback="30d")
if not results_df.empty:
print("\nShape of results_df in main:", results_df.shape)
print("First few rows of results_df in main:\n", results_df.head())
print("\nLast few rows of results_df in main:\n", results_df.tail())
else:
print("Could not generate Bollinger Bands.")
# Simulate new data arrival
today = pd.Timestamp('today').strftime('%Y-%m-%d')
yesterday = (pd.Timestamp('today') - pd.Timedelta(days=1)).strftime('%Y-%m-%d')
new_data_df = yf.download(f"{ticker}.NS", start=yesterday, end=today)['Close'].dropna()
if not new_data_df.empty:
last_price = new_data_df.iloc[-1]
new_row = pd.Series({'Close': last_price})
if not results_df.empty:
results_df = pd.concat([results_df, new_row.to_frame().T], ignore_index=False)
# Recalculate indicators
indicator = ta.volatility.BollingerBands(close=results_df['Close'], window=20, window_dev=2)
results_df['bb_mid'] = indicator.bollinger_mavg()
results_df['bb_upper'] = indicator.bollinger_hband()
results_df['bb_lower'] = indicator.bollinger_lband()
results_df['squeeze_on'] = (results_df['bb_upper'] - results_df['bb_lower']) <= (results_df['bb_mid'].rolling(20).std() * 2)
results_df['squeeze_breakout_long'] = (results_df['Close'] > results_df['bb_upper']) & (results_df['squeeze_on'].shift(1) == True)
results_df['squeeze_breakout_short'] = (results_df['Close'] < results_df['bb_lower']) & (results_df['squeeze_on'].shift(1) == True)
print("\nShape of updated results_df:", results_df.shape)
print("\nLast few rows of updated results_df:\n", results_df.tail())
else:
print("\nInitial DataFrame was empty, cannot append new data.")
else:
print("\nCould not fetch new daily data for simulation.")
[*********************100%***********************] 1 of 1 completed
Shape of 'close_prices' (pandas Series): (30, 1) First few rows of 'close_prices': Ticker RELIANCE.NS Date 2025-03-10 1238.400024 2025-03-11 1247.300049 2025-03-12 1257.050049 2025-03-13 1247.900024 2025-03-17 1238.849976
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[25], line 57 55 if __name__ == "__main__": 56 ticker = "RELIANCE" ---> 57 results_df = bollinger_bands_strategy(ticker, lookback="30d") 58 if not results_df.empty: 59 print("\nShape of results_df in main:", results_df.shape) Cell In[25], line 43, in bollinger_bands_strategy(ticker, period, std_dev, lookback) 39 print("First few rows of 'close_prices':\n", close_prices.head()) 42 indicator = ta.volatility.BollingerBands(close=close_prices, window=period, window_dev=std_dev) ---> 43 bb_mid = indicator.bollinger_mavg() 44 bb_upper = indicator.bollinger_hband() 45 bb_lower = indicator.bollinger_lband() File ~\anaconda3\Lib\site-packages\ta\volatility.py:108, in BollingerBands.bollinger_mavg(self) 102 """Bollinger Channel Middle Band 103 104 Returns: 105 pandas.Series: New feature generated. 106 """ 107 mavg = self._check_fillna(self._mavg, value=-1) --> 108 return pd.Series(mavg, name="mavg") File ~\anaconda3\Lib\site-packages\pandas\core\series.py:584, in Series.__init__(self, data, index, dtype, name, copy, fastpath) 582 data = data.copy() 583 else: --> 584 data = sanitize_array(data, index, dtype, copy) 586 manager = _get_option("mode.data_manager", silent=True) 587 if manager == "block": File ~\anaconda3\Lib\site-packages\pandas\core\construction.py:633, in sanitize_array(data, index, dtype, copy, allow_2d) 631 else: 632 data = np.array(data, copy=copy) --> 633 return sanitize_array( 634 data, 635 index=index, 636 dtype=dtype, 637 copy=False, 638 allow_2d=allow_2d, 639 ) 641 else: 642 _sanitize_non_ordered(data) File ~\anaconda3\Lib\site-packages\pandas\core\construction.py:659, in sanitize_array(data, index, dtype, copy, allow_2d) 656 subarr = cast(np.ndarray, subarr) 657 subarr = maybe_infer_to_datetimelike(subarr) --> 659 subarr = _sanitize_ndim(subarr, data, dtype, index, allow_2d=allow_2d) 661 if isinstance(subarr, np.ndarray): 662 # at this point we should have dtype be None or subarr.dtype == dtype 663 dtype = cast(np.dtype, dtype) File ~\anaconda3\Lib\site-packages\pandas\core\construction.py:718, in _sanitize_ndim(result, data, dtype, index, allow_2d) 716 if allow_2d: 717 return result --> 718 raise ValueError( 719 f"Data must be 1-dimensional, got ndarray of shape {data.shape} instead" 720 ) 721 if is_object_dtype(dtype) and isinstance(dtype, ExtensionDtype): 722 # i.e. NumpyEADtype("O") 724 result = com.asarray_tuplesafe(data, dtype=np.dtype("object")) ValueError: Data must be 1-dimensional, got ndarray of shape (30, 1) instead
In [33]:
import yfinance as yf
import pandas as pd
import ta
def calculate_rsi(ticker, period=14, lookback="100d"):
df = yf.download(ticker, period=lookback)
if df.empty:
print(f"Could not retrieve data for {ticker}.")
return None
close_prices = df['Close'].squeeze().dropna()
rsi_indicator = ta.momentum.RSIIndicator(close=close_prices, window=period)
rsi = rsi_indicator.rsi()
rsi_df = pd.DataFrame({'Close': close_prices, 'RSI': rsi})
return rsi_df
if __name__ == "__main__":
stock_ticker = "RELIANCE.NS"
rsi_period = 14
historical_lookback = "365d"
rsi_data = calculate_rsi(stock_ticker, period=rsi_period, lookback=historical_lookback)
if rsi_data is not None:
print(f"RSI for {stock_ticker} (Period: {rsi_period}, Lookback: {historical_lookback}):")
print(rsi_data.tail(20))
else:
print("RSI calculation failed.")
close_prices = df['Close'].squeeze().dropna()
[*********************100%***********************] 1 of 1 completed
RSI for RELIANCE.NS (Period: 14, Lookback: 365d):
Close RSI
Date
2025-03-25 1285.449951 61.661602
2025-03-26 1273.050049 57.554981
2025-03-27 1278.199951 58.782744
2025-03-28 1275.099976 57.700779
2025-04-01 1252.599976 50.443446
2025-04-02 1251.150024 50.006949
2025-04-03 1248.699951 49.231717
2025-04-04 1204.699951 37.875811
2025-04-07 1165.699951 31.041225
2025-04-08 1182.199951 36.280004
2025-04-09 1185.349976 37.259945
2025-04-11 1218.949951 46.679461
2025-04-15 1240.099976 51.604866
2025-04-16 1239.300049 51.411433
2025-04-17 1274.500000 58.740390
2025-04-21 1295.500000 62.385612
2025-04-22 1291.199951 61.193431
2025-04-23 1300.000000 62.761782
2025-04-24 1301.599976 63.054141
2025-04-25 1300.400024 62.656829
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[33], line 35 32 else: 33 print("RSI calculation failed.") ---> 35 close_prices = df['Close'].squeeze().dropna() NameError: name 'df' is not defined
In [35]:
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
data = yf.download('RELIANCE.NS', start='2023-01-01', end='2024-01-01')
def calculate_rsi(data, window=14):
delta = data['Close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
data['RSI'] = calculate_rsi(data)
# Plot RSI
plt.figure(figsize=(12, 6))
plt.plot(data['RSI'], label='RSI', color='blue')
plt.axhline(70, color='red', linestyle='--', label='Overbought Threshold')
plt.axhline(30, color='green', linestyle='--', label='Oversold Threshold')
plt.title('RSI of Reliance Stock (RELIANCE.NS)')
plt.xlabel('Date')
plt.ylabel('RSI')
plt.legend()
plt.grid()
plt.show()
[*********************100%***********************] 1 of 1 completed
In [37]:
import numpy as np
import pandas as pd
import yfinance as yf
import ta
def calculate_returns(df, risk_free_rate=0.06):
"""Calculates Annualized and Cumulative returns for a given DataFrame with 'Close' prices.
Args:
df (pd.DataFrame): DataFrame containing 'Close' prices.
risk_free_rate (float): Annual risk-free rate (default: 0.06).
Returns:
pd.Series: A Series containing the calculated returns.
"""
returns = df['Close'].pct_change().dropna()
n = len(returns)
trading_days = 252 # Approximate number of trading days in a year
# Cumulative Return
cumulative_return = (1 + returns).prod() - 1
# Annualized Return
annualized_return = ((1 + cumulative_return) ** (trading_days / n)) - 1
return pd.Series({
'Cumulative Return': cumulative_return,
'Annualized Return': annualized_return,
})
def get_stock_returns(ticker, risk_free_rate=0.06, period="1y"):
"""Fetches stock data and calculates returns.
Args:
ticker (str): Stock ticker symbol.
risk_free_rate (float): Annual risk-free rate (default: 0.06).
period (str): The time period for which to retrieve stock data.
Valid values are yfinance period strings (e.g., "1y", "5y", "max").
Returns:
pd.DataFrame: containing the returns, or None if data retrieval fails.
"""
try:
df = yf.download(ticker, period=period)
if df.empty:
print(f"No data found for ticker: {ticker}")
return None
returns_series = calculate_returns(df, risk_free_rate)
print(returns_series)
# Create a DataFrame for the returns with date
returns_df = pd.DataFrame(returns_series).transpose()
returns_df.index = [ticker]
return returns_df
except Exception as e:
print(f"Error fetching data or calculating returns for {ticker}: {e}")
return None
if __name__ == '__main__':
# Example usage
stock_ticker = 'RELIANCE.NS'
risk_free_rate = 0.06
returns_df = get_stock_returns(stock_ticker, risk_free_rate)
if returns_df is not None:
print(f"Returns for {stock_ticker}:")
print(returns_df)
else:
print(f"Could not retrieve returns for {stock_ticker}")
[*********************100%***********************] 1 of 1 completed
Cumulative Return Ticker
RELIANCE.NS -0.106277
dtype: float64
Annualized Return Ticker
RELIANCE.NS -0.108307
dtype: float64
dtype: object
Returns for RELIANCE.NS:
Cumulative Return \
RELIANCE.NS Ticker
RELIANCE.NS -0.106277
dtype: float64
Annualized Return
RELIANCE.NS Ticker
RELIANCE.NS -0.108307
dtype: float64
In [39]:
import yfinance as yf
import numpy as np
import pandas as pd
data = yf.download("RELIANCE.NS", start="2023-01-01", end="2024-01-01")
benchmark_data = yf.download("^NSEI", start="2023-01-01", end="2024-01-01")
print("Columns in data:", data.columns)
close_col = 'Adj Close' if 'Adj Close' in data.columns else 'Close'
# Calculate daily returns
data['Returns'] = data[close_col].pct_change()
benchmark_data['Benchmark_Returns'] = benchmark_data[close_col].pct_change()
rf = 0.06 / 252
sharpe = (data['Returns'].mean() - rf) / data['Returns'].std()
neg_returns = data['Returns'][data['Returns'] < 0]
sortino = (data['Returns'].mean() - rf) / neg_returns.std()
cumulative = (1 + data['Returns']).cumprod()
rolling_max = cumulative.cummax()
drawdown = (cumulative - rolling_max) / rolling_max
max_dd = drawdown.min()
win_rate = (data['Returns'] > 0).mean()
profits = data['Returns'][data['Returns'] > 0]
losses = data['Returns'][data['Returns'] < 0]
profit_factor = profits.sum() / abs(losses.sum())
avg_profit = profits.mean()
avg_loss = losses.mean()
max_profit = profits.max()
max_loss = losses.min()
reliance_cum_return = (1 + data['Returns']).prod() - 1
nifty_cum_return = (1 + benchmark_data['Benchmark_Returns']).prod() - 1
relative_perf = reliance_cum_return - nifty_cum_return
`
print(f"📈 Sharpe Ratio: {sharpe:.3f}")
print(f"📉 Sortino Ratio: {sortino:.3f}")
print(f"📉 Max Drawdown: {max_dd:.2%}")
print(f"✅ Win Rate: {win_rate:.2%}")
print(f"💰 Profit Factor: {profit_factor:.2f}")
print(f" ↳ Avg Profit: {avg_profit:.2%}, Avg Loss: {avg_loss:.2%}")
print(f" ↳ Max Profit: {max_profit:.2%}, Max Loss: {max_loss:.2%}")
print(f"🇮🇳 RELIANCE Return: {reliance_cum_return:.2%}")
print(f"📊 NIFTY50 Return: {nifty_cum_return:.2%}")
print(f"🆚 Relative Outperformance: {relative_perf:.2%}")
[*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed
Columns in data: MultiIndex([( 'Close', 'RELIANCE.NS'),
( 'High', 'RELIANCE.NS'),
( 'Low', 'RELIANCE.NS'),
( 'Open', 'RELIANCE.NS'),
('Volume', 'RELIANCE.NS')],
names=['Price', 'Ticker'])
📈 Sharpe Ratio: 0.016
📉 Sortino Ratio: 0.028
📉 Max Drawdown: -15.23%
✅ Win Rate: 50.20%
💰 Profit Factor: 1.11
↳ Avg Profit: 0.86%, Avg Loss: -0.79%
↳ Max Profit: 4.31%, Max Loss: -3.10%
🇮🇳 RELIANCE Return: 9.11%
📊 NIFTY50 Return: 19.42%
🆚 Relative Outperformance: -10.31%
In [7]:
import yfinance as yf
import pandas as pd
# Download historical data
data = yf.download('RELIANCE.NS', start='2023-01-01', end='2024-01-01')
# Calculate moving averages
data['SMA50'] = data['Close'].rolling(window=50).mean()
data['SMA200'] = data['Close'].rolling(window=200).mean()
# Generate trading signals
data['Signal'] = 0
data.loc[data['SMA50'] > data['SMA200'], 'Signal'] = 1
data.loc[data['SMA50'] < data['SMA200'], 'Signal'] = -1
print(data[['Close', 'SMA50', 'SMA200', 'Signal']].tail(10))
# Margin calculations
data['Trade_Value'] = data['Close'] # Assuming full position entry at close price
data['Margin_Required'] = data['Trade_Value'] * 0.20 # 20% margin requirement
initial_capital = 100000 # Example starting capital
data['Margin_Utilization'] = data['Margin_Required'] / initial_capital * 100 # Percentage of capital used
# Risk measurements
data['Returns'] = data['Close'].pct_change()
data['Volatility'] = data['Returns'].rolling(window=50).std()
data['Max_Drawdown'] = (data['Close'] - data['Close'].cummax()) / data['Close'].cummax()
print(data[['Margin_Required', 'Margin_Utilization', 'Returns', 'Volatility', 'Max_Drawdown']].tail(10))
[*********************100%***********************] 1 of 1 completed
1 Failed download:
['RELIANCE.NS']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
Empty DataFrame Columns: [(Close, RELIANCE.NS), (SMA50, ), (SMA200, ), (Signal, )] Index: [] Empty DataFrame Columns: [(Margin_Required, ), (Margin_Utilization, ), (Returns, ), (Volatility, ), (Max_Drawdown, )] Index: []
In [ ]: